package com.siyoumi.task;

import com.siyoumi.component.XApp;
import com.siyoumi.component.XRedis;
import com.siyoumi.component.XRedisLock;
import com.siyoumi.config.SysConfig;
import com.siyoumi.controller.BaseController;
import com.siyoumi.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;

//任务接口
@Slf4j
abstract public class TaskController
        extends BaseController {

    public String getLockKeyFix() {
        return "";
    }

    public String lockKey() {
        String key = XStr.concat("JOB:", getClass().getSimpleName());
        String lockKeyFix = getLockKeyFix();
        if (XStr.hasAnyText(lockKeyFix)) {
            key += "|" + lockKeyFix;
        }

        log.debug(key);
        return key;
    }

    /**
     * 只处理1次
     */
    protected Boolean handle1() {
        return true;
    }

    /**
     * 单次执行任务，次数及参数
     */
    protected abstract List handleData();

    /**
     * 执行任务-前处理（如：setx操作）
     *
     * @param data
     */
    protected abstract void handleBefore(Object data);

    /**
     * 执行任务的逻辑
     *
     * @param data
     */
    protected abstract XReturn handle(Object data);


    //主方法
    @GetMapping()
    final public XReturn index() {
        String className = getClass().getSimpleName();
        log.debug(className + " BEGIN");
        //同1个任务，只能同时运行1个
        XReturn rr = XRedisLock.tryLockFunc(lockKey(), k -> {
            Integer runMax = 200;

            XReturn r = XReturn.getR(0);
            for (int i = 0; i < runMax; i++) {
                List listData = handleData();
                if (listData.size() <= 0) {
                    break;
                }

                Boolean taskStop = false;
                //执行任务
                for (Object itemData : listData) {
                    handleBefore(itemData);
                    r = handle(itemData);
                    log.debug(XJson.toJSONString(r));
                    if (r.getErrCode().equals(EnumTask.STOP.getErrcode())) {
                        //停止任务
                        taskStop = true;
                        break;
                    }
                }

                if (taskStop) {
                    log.debug("任务中断");
                    break;
                }

                if (handle1()) {
                    log.debug("任务只执行1次");
                    break;
                }

                XApp.sleep(1);
            }

            return r;
        });
        //记录任务最后一次运行时间
        String key = SysConfig.getIns().getEnv() + "|task";
        XRedis.getBean().getList(key).put(className, XDate.toDateTimeString());
        log.debug(className + " END");

        return rr;
    }
}
